package com.easy;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import static java.util.concurrent.Executors.newFixedThreadPool;

/**
 * @author liuyang
 * 2021/3/18 7:28 下午
 */
@Slf4j
public class NoModel2DataListener extends AnalysisEventListener<Map<Integer, String>> {


    private static final int COUNT = 20000;

    private ExecutorService executorService = newFixedThreadPool(9);

    private List<Map<Integer, String>> list = new ArrayList<Map<Integer, String>>();

    Map<Integer, String> header = new HashMap<>();

    private int currentIndex = 0;


    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) {
        if (analysisContext.readRowHolder().getRowIndex() == 0) {
            header = data;
        } else {
            list.add(data);
            currentIndex++;
            if (list.size() >= COUNT) {
                executorService.submit(new ExcelWrite(list.stream().map(LinkedHashMap::new).collect(Collectors.toList()), currentIndex));
                list.clear();
            }
        }


    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        executorService.submit(new ExcelWrite(new ArrayList<>(list), currentIndex));
        executorService.shutdown();
    }

    private List<List<String>> head() {
        List<List<String>> h = new ArrayList<>();
        for (Map.Entry<Integer, String> entry : header.entrySet()) {
            List<String> i = Arrays.asList(entry.getValue());
            h.add(i);
        }
        return h;
    }

    private List<List<Object>> dataList(List<Map<Integer, String>> data) {
        List<List<Object>> result = new ArrayList<>();
        for (Map<Integer, String> d : data) {
            List<Object> t = new ArrayList<>();
            for (Map.Entry<Integer, String> entry : d.entrySet()) {
                t.add(entry.getValue());
            }
            result.add(t);
        }

        return result;
    }

    class ExcelWrite implements Runnable {

        private int index;

        private List<Map<Integer, String>> data;

        ExcelWrite(List<Map<Integer, String>> data, int index) {
            this.data = data;
            this.index = index;
        }

        @Override
        public void run() {
            String fileName = this.getClass().getResource("").getPath() + index + ".xlsx";
            long beginTime = System.currentTimeMillis();
            EasyExcel.write(fileName).head(head()).useDefaultStyle(false).sheet("fuck").doWrite(dataList(data));
            log.info("分割文件{},执行耗时{}秒", fileName, (System.currentTimeMillis() - beginTime) / 1000f);
            System.out.println("end task ");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        String fileName = NoModel2DataListener.class.getClassLoader().getResource("template").getPath()+ File.separator+"商机基本信息-大网.xlsx";
        long beginTime = System.currentTimeMillis();
        EasyExcel.read(fileName, new NoModel2DataListener()).sheet().headRowNumber(0).doRead();
        log.info("源文件{},总执行耗时{}秒", fileName, (System.currentTimeMillis() - beginTime) / 1000f);
        System.out.println("main - end");
    }
}
